﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using Reinforcement;

namespace sau
{
    public class ProcessLoop
    {
        private CCEnvironment model;
        private CCDecisionMaker advisor;

        private Thread aircraftThread;

        private int sleepTime = 20;

        Form1 form1;

        int stepNumber = 1;

        public ProcessLoop()
        {
            model = new AircraftModel();
            advisor = new Advisor();
        }

        public void StartThread()
        {
            aircraftThread = new Thread(new ThreadStart(MainLoop));
            aircraftThread.Start();
        }

        public void MainLoop()
        {
            bool beginFlag = true;

            double[] state = new double[4];
            double[] decision = new double[1];
            double[] state_decision = new double[5];
            double reward = 0.0;

            while (true)
            {
                if (beginFlag)
                {
                    stepNumber = 1;

                    model.CCStartInRandomState();
                    model.CCGetCurrentState(ref state, ref state);

                    advisor.CCStartInState(state);

                    beginFlag = false;
                }

                advisor.CCAdviseAction(ref decision);
                model.CCMove(decision, ref reward);
                model.CCGetCurrentState(ref state, ref state);

                //end of epizod
                if (stepNumber > 1 && (state[2] > 0.6 || state[2] < -0.6))
                {
                    reward = -10;
                    beginFlag = true;
                }

                advisor.CCThisHappened(reward, state);

                for (int i = 0; i < 4; ++i)
                {
                    state_decision[i] = state[i];
                }
                state_decision[4] = decision[0];

                // Send to view required data.
                form1.Invoke(form1.painterDelegate, state_decision);

                stepNumber++;

                //end of epizod
                //if (stepNumber > 500 && reward < 1.0)
                //{
                //    beginFlag = true;
                //}

                Thread.Sleep(sleepTime);
            }
        }

        public void SetForm(Form1 form)
        {
            form1 = form;
        }
    }
}
